#include "Cargo.h"
#include <sstream>
#include "Utils.h"
using namespace Entidades;

Cargo::Cargo() {
	this->cargosAsociados = new vector<Cargo*> ();
}

string Cargo::getNombre() const {
	return this->nombre;
}

vector<Cargo*>* Cargo::getCargosAsociados() const {
	return this->cargosAsociados;
}

void Cargo::setNombre(string nombre) {
	this->nombre = nombre;
}

void Cargo::agregarCargoAsociado(Cargo* cargoAsociado) {
	this->cargosAsociados->push_back(cargoAsociado);
}

void Cargo::hidratarse(char* buffer, unsigned int tamanioDelBuffer) {

	//escribo el buffer en el stringStream
	stringstream* ss = new stringstream(stringstream::in | stringstream::out | stringstream::binary);
	ss->seekg(0, ios::beg);
	ss->write(buffer, tamanioDelBuffer);

	//nombreCargoPrincipal string
	this->nombre = Utils::ObtenerSiguienteStringVariable(ss);

	//Cargos asociados (numeroDeCargosAsociados int | cargo1 string | cargo2 string)
	unsigned int numeroDeCargosAsociados;
	ss->read((char*) &(numeroDeCargosAsociados), sizeof(int));
	for (unsigned int i = 0; i < numeroDeCargosAsociados; i++) {
		Cargo* cargoAsociado = new Cargo();
		cargoAsociado->setNombre(Utils::ObtenerSiguienteStringVariable(ss));
		this->cargosAsociados->push_back(cargoAsociado);
	}

	delete ss;
}

char* Cargo::construirBuffer() {
	// guardo: nombreCargoPpal string | numeroDeCargosAsociados int | cargo1 string | cargo2 string | ...

	//agrupo los atributos
	stringstream* ss = new stringstream(stringstream::in | stringstream::out | stringstream::binary);
	ss->seekp(0, ios::end);

	//nombreCargoPpal string
	unsigned int tamanioNombreDelCargoPrincipal = this->nombre.size();
	ss->write((char*) &tamanioNombreDelCargoPrincipal, sizeof(int));
	ss->write(this->nombre.c_str(), tamanioNombreDelCargoPrincipal);

	//Cargos asociados (numeroDeCargosAsociados int | cargo1 string | cargo2 string | ... )
	unsigned int numeroDeCargosAsociados = this->cargosAsociados->size();
	ss->write((char*) &(numeroDeCargosAsociados), sizeof(int));
	unsigned int *tamanioDeCargoAsociado = new unsigned int();
	for (unsigned int i = 0; i < numeroDeCargosAsociados; i++) {
		*tamanioDeCargoAsociado = this->cargosAsociados->at(i)->getNombre().size();
		ss->write((char*) tamanioDeCargoAsociado, sizeof(int));
		ss->write(this->cargosAsociados->at(i)->getNombre().c_str(), *tamanioDeCargoAsociado);
	}
	delete tamanioDeCargoAsociado;

	//construyo el buffer
	unsigned int tamanioDelBuffer = this->getTamanioDelBuffer();
	char* buffer = new char[tamanioDelBuffer];
	ss->read(buffer, tamanioDelBuffer);
	delete ss;

	//lo devuelvo
	return buffer;
}

unsigned int Cargo::getTamanioDelBuffer() {
	unsigned int tamanioDelBuffer = (2 * sizeof(int)) + this->nombre.size();

	for(unsigned int i = 0; i < cargosAsociados->size();i++){
		tamanioDelBuffer += sizeof(int) + cargosAsociados->at(i)->getNombre().size();
	}

	return tamanioDelBuffer;
}

void Cargo::marcarComoBorrado() {
	this->setNombre("");
}

Cargo::~Cargo() {

	for (unsigned int i = 0; i < cargosAsociados->size(); i++) {
		delete this->cargosAsociados->at(i);
	}

	delete this->cargosAsociados;
}

